<?php

namespace common\service;

use common\exception\LogicException;
use common\model\UserModel;
use support\ErrorCode;

class FinanceReviewWorkflowService extends ReviewWorkflowService
{
    /**
     * 匹配审批流里的人
     * @param $reviewWorkflowId
     * @return array
     * @throws \Exception
     */
    public function selectReview($reviewWorkflowId)
    {
        $userService = UserService::getInstance();
        $userId = request()->getUserId();
        //审批流查询
        $reviewFilter = [
            'id' => $reviewWorkflowId,
            'active' => "yes",
            'is_deleted' => "no",
        ];
        $nodesData = $this->getWorkflow(["id,name,description,config"], $reviewFilter);

        if (empty($nodesData)) {
            throw new LogicException("can`t found a active review workflow", ErrorCode::REVIEW_WORKFLOW_CONFIG_NOT_FOUND);
        }
        //解析节点
        $nodesData['config'] = json_decode($nodesData['config'], true);
        list($promoter, $reviewers,) = $this::parseConfig($nodesData['config']['nodes']);

        $userInfo = teamones_request('teamones-im', 'user/get_my_user_info', null)['data'];
        $saasUser = model(UserModel::class)->find($userId);

        // 组装部门id列表
        $myDepartmentInfoList = $userInfo['department_info'] ?? [];
        $departmentIdList = array_column($myDepartmentInfoList, 'id');
        $reviewerRoles = array_column($reviewers, 'role');
        $requestData = ["param" => [
            "filter" => [
                "role.code" => ['-in', implode(',', $reviewerRoles)]
            ],
            "fields" => "role.id,role.name,role.code"
        ]];
        $roleInfo = teamones_request('teamones-im', 'role/select', $requestData)['data'];

        if (empty($roleInfo)) {
            throw new LogicException("has not enough users to execute workflow", ErrorCode::NOT_ENOUGH_USERS_TO_EXECUTE_WORKFLOW);
        }
        $roleInfo = $roleInfo['rows'];
        $roleNameMap = array_column($roleInfo, 'name', 'code');
        $reviewersData = [];
        $leftReviewerRoles = $reviewerRoles;

        $reviewerSearchedIndex = -1;

        $users = [];
        if (!empty($leftReviewerRoles)) {
            //远端获取租户用户和角色信息
            try {
                $requestData = ["param" => [
                    "filter" => [
                        "role.code" => ["-in", implode(',', $leftReviewerRoles)]
                    ],
                ]];
                $users = teamones_request('teamones-im', 'tenant/select_tenant_user', $requestData)['data'];
            } catch (\Throwable $e) {
                trace(format_exception_info($e), 'ERR');
                throw new LogicException("get user from remote failed", ErrorCode::GET_USER_FROM_REMOTE_FAILED);
            }
            if (empty($users)) {
                throw new LogicException("has not enough users to execute step check workflow", ErrorCode::NOT_ENOUGH_USERS_TO_EXECUTE_STEP_CHECK_WORKFLOW);
            }
        }

        //通过部门分组用户
        $usersGroupByDepartment = [];
        foreach ($users as $userIndex => &$user) {
            $user['role_code'] = [];
            if (!empty($user['role_info'])) {
                $user['role_code'] = array_column($user['role_info'], 'code');
            }
            foreach ($user['department_info'] as $department) {
                $usersGroupByDepartment[$department['id']][] = $users[$userIndex];
            }
        }

        foreach ($reviewerRoles as $roleIndex => $role) {
            if ($roleIndex <= $reviewerSearchedIndex) {
                //自动跳过能跳过的节点
                $reviewersData[] = [
                    'role_name' => $roleNameMap[$role],
                    "role_code" => $role,
                    "user_info" => [
                        $saasUser
                    ],
                    "skip" => 1,
                    'user_id' => 0,
                ];
                continue;
            }

            $reviewerUsers = [];
            //处理特殊情况
            switch ($role) {
                case TaskService::HEADMAN_CODE:
                    $reviewerUsers = array_filter($users, function ($item) use ($role) {
                        return in_array($role, $item['role_code']);
                    });
                    break;
                case TaskService::DIRECTOR_CODE:
                case TaskService::PRODUCER_CODE:
                case TaskService::ARTILIST_CODE:
                    //艺术家或者其他角色 直接进默认
                default:
                    //优先从本部门查  然后在租户里查
                    foreach ($departmentIdList as $departmentId) {
                        $reviewerUsers = array_filter($usersGroupByDepartment[$departmentId] ?? [], function ($item) use ($role) {
                            return in_array($role, $item['role_code']);
                        });
                    }
                    if (empty($reviewerUsers)) {
                        //查不到用户 就从租户里查
                        $reviewerUsers = array_filter($users, function ($item) use ($role) {
                            return in_array($role, $item['role_code']);
                        });
                    }
            }

            if (count($reviewerUsers) == 0) {
                throw new LogicException("can`t found a {$role}", ErrorCode::ROLE_NOT_FOUND);
            }

            if (count($reviewerUsers) == 1) {
                $user = $userService->getUserByUnionId(array_shift($reviewerUsers)['user_id'], true);
                $reviewersData[] = [
                    'role_name' => $roleNameMap[$role],
                    "role_code" => $role,
                    "user_info" => [$user],
                    "skip" => 0,
                    'user_id' => 0,
                ];
            } else {
                $userIds = array_column($reviewerUsers, 'user_id', 'user_id');
                $usersLocal = $userService->getUsersByUnionIds($userIds, "id,name,avatar,phone,email", true);
                $reviewersData[] = [
                    'role_name' => $roleNameMap[$role],
                    "role_code" => $role,
                    "user_info" => $usersLocal,
                    "skip" => 0,
                    'user_id' => 0,
                ];
            }
        }

        return [
            "review_workflow" => $nodesData,
            "matched_data" => [
                'promoter' => $promoter,
                'reviewers' => $reviewersData,
                'self_info' => $userInfo,
            ],
        ];
    }
}
